package game.frame;

import game.action.WorkPanelKeyAction;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

public class WorkPanel extends JPanel implements WorkPanelIfc {
	
	private int posX = 10;
	private int posY = 10;
	private int width = 481;
	private int height = 481;
	private int cellSize = 10;
	
	private boolean gridFlag = false;
	private boolean gameEnable = false;
	private int 	modeMoving = 0;
	private Snake snake = null;
	private SnakeFood snakeFood = null;
	private Direction dir = Direction.None; 
	
	public WorkPanel() {
		super();
		
		WorkPanelKeyAction keyAction = new WorkPanelKeyAction();
		
		setLayout(null);
		setBounds(posX, posY, width, height);
		setOpaque(true);
		setBackground(new Color(0, 25, 0));
		initializeGame();
		
		//-- Add Action
		addKeyListener(keyAction);
		setFocusable(true);
		requestFocus();
		
		setVisible(true);
	}
	
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		//-- Cat to graphic 2D
		Graphics2D g2D = (Graphics2D) g;

		g2D.setColor(Color.RED);
		g2D.drawRect(0, 0, width - 1, height - 1);
		
		if(gameEnable) {
			drawGrid(g2D);
			
			//-- draw snake
			for (CellPoint cp : snake.getSnakeBody()) {
				cp.drawCellPoint(g2D, (WorkPanelIfc) this, false);
			}
			
			//-- draw food
			snakeFood.drawFood(g2D);
		}
	}
	
	public void initializeGame() {
		setGridFlag(false);
		setGameEnable(true);
		this.modeMoving = 2;
		
		//-- Initializing the snake body
		snake  = new Snake(16, this);
		snakeFood = new SnakeFood((WorkPanelIfc) this);
		
		repaint();
	}
	
	public void updateSnakePos() {
		boolean moved = snake.snakeMove(modeMoving, dir);
		if(!moved) {
			this.dir = snake.getDir();
		}
		
		repaint();
	}
	
	public void drawGrid(Graphics2D g) {
		if(! gridFlag) {
			return; //-- escape when no draw Grid
		}
		
//		g.setColor(Color.ORANGE);
		g.setColor(Color.GRAY);
		
		//-- Horizontal
		for(int i = cellSize; i <= width - cellSize; i += cellSize) {
			g.drawLine(1, i, width - 2, i);
		}
		//-- Vertical
		for(int i = cellSize; i <= height - cellSize; i += cellSize) {
			g.drawLine(i, 0, i, height - 2);
		}
	}

	public int getPosX() {
		return posX;
	}

	public int getPosY() {
		return posY;
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	public int getCellSize() {
		return cellSize;
	}

	public boolean isGridFlag() {
		return gridFlag;
	}

	public boolean isGameEnable() {
		return gameEnable;
	}

	public int getModeMoving() {
		return modeMoving;
	}

	public Direction getDir() {
		return dir;
	}

	public SnakeFood getSnakeFood() {
		return snakeFood;
	}

	public void setSnakeFood(SnakeFood snakeFood) {
		this.snakeFood = snakeFood;
	}

	public void setDir(Direction dir) {
		this.dir = dir;
	}

	public void setModeMoving(int modeMoving) {
		this.modeMoving = modeMoving;
	}

	public void setPosX(int posX) {
		this.posX = posX;
	}

	public void setPosY(int posY) {
		this.posY = posY;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public void setCellSize(int cellSize) {
		this.cellSize = cellSize;
	}

	public void setGridFlag(boolean gridFlag) {
		this.gridFlag = gridFlag;
	}

	public void setGameEnable(boolean gameEnable) {
		this.gameEnable = gameEnable;
	}

	/**
	 * @return the snake
	 */
	public Snake getSnake() {
		return snake;
	}

	/**
	 * @param snake the snake to set
	 */
	public void setSnake(Snake snake) {
		this.snake = snake;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + cellSize;
		result = prime * result + height;
		result = prime * result + posX;
		result = prime * result + posY;
		result = prime * result + width;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		WorkPanel other = (WorkPanel) obj;
		if (cellSize != other.cellSize)
			return false;
		if (height != other.height)
			return false;
		if (posX != other.posX)
			return false;
		if (posY != other.posY)
			return false;
		if (width != other.width)
			return false;
		return true;
	}

	public void setWorkPanleFocus() {
		requestFocus();		
	}
}
